最少改動 x 最大收益
有一個任務,要調整介面上的表格數據:
你發現有太多的其他功能,都要使用到這個數據。
這裡一改動,就代表了全部都要一起改。
兩者建立了依賴關係,這種行為在軟體中也會稱為:
「耦合」
高內聚 低耦合
要怎麼達成 ?
耦合性三大原則
可以先幫你實現低耦合的目標。
「軟體」是一種很神奇的東西,看似很自由,可以隨意添加新的功能。
自由的空間,反而會越來越少 (越來越難改動)
看似多了限制,卻反而能使得,未來的擴展空間 大大的增加。
「違反直覺」延伸閱讀 :
整潔的軟體設計與架構篇
除了「物件導向的五大設計原則」以外,還有「元件的內聚性原則」與「元件的耦合性原則」。
實際上的順序,應該是要:
內聚性先,而耦合性後
因為我個人認為「耦合性」的概念,比較好懂; 原則的部分,也相對容易,應用於開發上。
這次,會先說明耦合性的部分
下一篇章,會接著繼續說明內聚性的部分
在元件的依賴關係圖中不允許出現環
朝著穩定方向進行依賴
元件的抽象程度應該與元件的穩定程度一致
Acyclic Dependencies Principle
在元件的依賴關係圖中不允許出現環
從字面上來理解,就是元件在需要其他的元件工作時,之間構成的依賴關係,不可以是環狀循環。
因為依賴於其他元件,目的是為了
「減輕工作量」
別的元件有做過的事情,就不要重新再做一次。
如果元件的依賴會互相參照,代表 :
就好像構成了 一個短路循環 ,直到系統**「過載」**
從「減輕工作量」這個角度來看,「循環依賴」更像是一個工作製造機
可以源源不絕的,讓你有做不完的工作。(不會失業 XD)
Stable Dependencies Principle
朝著穩定方向進行依賴
延續無環依賴原則的思路,除了依賴不能造成循環,依賴還是最好有個方向。
這個方向的路標,就是「穩定度」
也是以「工作量」的多寡來決定
元件被很多的功能依賴,但本身沒有去依賴任何東西
改了它,就代表了巨大的「工作量」
所以這個元件是「穩定」的
如果這個元件,沒有功能依賴它,但它依賴了很多外部的元件
修改它的「工作量」非常的低
所以這個元件是「不穩定」的
藉由依賴的關係數量,這裡就會有一個的公式,可以計算元件的穩定度
理想的狀況,就是由不穩定的元件,朝向穩定的元件,建立依賴關係
Stable Abstractions Principle
元件的抽象程度 應該與元件的穩定程度一致
也就是越重要的元件,應該越只表達純粹的「概念」
穩定的核心元件,雖然穩定,但失去彈性不能擴增,並不是軟體設計想要看到的情況。
以餐廳來說,廚師就是穩定的核心元件
由廚師本身會煮什麼菜,來決定餐廳會有什麼樣的菜單
對於,有點規模的餐聽,這並不是一個好的情況
這邊的原則,就是將表達**「概念」的「菜單」**,當成是最穩定的核心元件
如此,就不會受到限制。各個連鎖店的廚師,也能根據菜單的菜譜,快速增加新的菜色。
依據耦合性的原則,領域驅動設計的概念,補充實作部份的三個細節:
通常就是系統的核心,所以 Domain 的 Service 通常會宣告成 Interface 的介面
名稱結尾為 Service
然後,在同目錄的 impl/ 資料夾,創建新的類別實作(implements) 該 Service 的介面
名稱結尾為 ServiceImpl
這裡是借鑒了 「SAP 穩定抽象原則」,越穩定的元件應該越抽象。
負責的是流程作業,相比於 Domain 層變動性是比較大的,雖然說同樣有 Service 的類別,但不再創建 Interface 的介面
結尾的名稱命名 使用 AppService
這裡是借鑒了 「SDP 穩定依賴原則」,把容易變動的東西,變得更加容易改動。
提供所有的技術支援,從 DDD 的架構分層可以很明顯地看到,它是個自上而下的依賴關係
但對於與 Domain 層的關係,我認為不應該被領域層的元件所依賴
DAO , Data Access Object
領域層(Domain Layer)的服務(Service) ,不應該直接 調用 DAO 來完成資料保存的任務
而是應該提升一個層級,交由應用層(Application) 來執行這項任務
避免資料庫的變動會影響到領域層(Domain Layer)的功能
util 工具,通常會是各種第三方的框架,封裝而來
如果,第三方的框架:
有重大的 bug
有更好的框架可以更換
調整 util 元件,就會影響到 領域層(Domain Layer) 的功能
這種情況...
不如就由領域層(Domain Layer) 提供 :
然後由,基礎設施層來實作功能。
不管最後是使用什麼樣的技術實作,只要能夠通過,領域層的單元測試,就可以確保系統的正確性。
這部分,可能一時之間無法轉換過來,不過這裡要表達的就是:
Domain 層 是穩定的核心元件,不應該去依賴其他層級的元件。
依據上述耦合性的三大原則,有沒有發現一件事情:
**「穩定」與「不穩定」**並不是一個「好」與「壞」的關係
而是這個「穩定度」與元件的「特性」是否是相符合。
最容易變動的「使用者介面層」、「應用層」,就是放在上兩層,向下依賴
不敢說是最好的「設計」,但我知道 :
建立關係
不應該是那麼的隨心所欲
朝著正確的方向不斷精進,也許哪一天也可以觸碰到傳說中:
「最少改動,最大收益」
軟體開發的天堂之境
只有資深工程師才有資格跟工程師說:「應該很簡單」
-- Gamma Ray Studio